package com.changgou.canal;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.annotation.Resource;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.changgou.config.RabbitmqConfig;
import com.changgou.content.feign.ContentFeign;
import com.changgou.content.pojo.Content;
import com.changgou.entity.Result;
import com.xpand.starter.canal.annotation.*;

/**
 * MySQL数据变动监听
 *
 * @author gaofeng
 * @date 2025年04月22日 16:57
 */
@CanalEventListener
public class CanalDataEventListener {
    @Resource
    private ContentFeign contentFeign;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RabbitTemplate rabbitTemplate;

    private static final String AUDIT_STATUS = "status";
    private static final String IS_MARKETABLE = "is_marketable";

    /**
     * 监听数据增加
     *
     * @param eventType 操作类型
     * @param data 发生变更的数据
     */
    @InsertListenPoint
    public void onInsertEvent(CanalEntry.EventType eventType, CanalEntry.RowData data) {
        data.getAfterColumnsList().forEach(column -> {
            System.out.println("列名--" + column.getName() + ":" + "新增的数据--" + column.getValue());
        });
    }

    /**
     * 监听数据删除
     *
     * @param eventType 操作类型
     * @param data 删除的数据
     */
    @DeleteListenPoint
    public void onDeleteEvent(CanalEntry.EventType eventType, CanalEntry.RowData data) {
        data.getBeforeColumnsList().forEach(column -> {
            System.out.println("列名--" + column.getName() + ":" + "删除的数据--" + column.getValue());
        });
    }

    /**
     * 监听数据修改
     *
     * @param data 修改的数据
     */
    @UpdateListenPoint(schema = "changgou_goods", table = {"tb_spu"}, destination = "example")
    public void onUpdateEvent(CanalEntry.EventType eventType, CanalEntry.RowData data) {
        // 商品审核通过，发送mq消息，通知静态页面生成服务生成静态页面
        List<CanalEntry.Column> updateColumns = data.getAfterColumnsList();
        Map<String, String> columnValueMap =
            updateColumns.stream().collect(HashMap::new, (m, v) -> m.put(v.getName(), v.getValue()), HashMap::putAll);
        if (columnValueMap.containsKey(AUDIT_STATUS) && columnValueMap.containsKey(IS_MARKETABLE)
            && "1".equals(columnValueMap.get(AUDIT_STATUS)) && "1".equals(columnValueMap.get(IS_MARKETABLE))) {
            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME, RabbitmqConfig.ROUTING_KEY,
                columnValueMap.get("id"));
        }
    }

    /**
     * 自定义监听
     *
     * @param eventType 操作类型
     * @param data 变更的数据
     */
    @ListenPoint(eventType = {CanalEntry.EventType.UPDATE, CanalEntry.EventType.INSERT, CanalEntry.EventType.DELETE},
        schema = "changgou_content", table = {"tb_content", "tb_content_category"}, destination = "example")
    public void onCustomerEvent(CanalEntry.EventType eventType, CanalEntry.RowData data) {
        String categoryId = getCategoryId(eventType, data);
        Result<List<Content>> categoryList = contentFeign.findByCategory(Long.valueOf(categoryId));
        List<Content> contents = categoryList.getData();
        stringRedisTemplate.boundValueOps("content_" + categoryId).set(JSON.toJSONString(contents));
    }

    private String getCategoryId(CanalEntry.EventType eventType, CanalEntry.RowData data) {
        String categoryId = null;
        if (Objects.equals(eventType, CanalEntry.EventType.DELETE)) {
            for (CanalEntry.Column column : data.getBeforeColumnsList()) {
                if ("category_id".equalsIgnoreCase(column.getName())) {
                    categoryId = column.getValue();
                }
            }
        } else {
            for (CanalEntry.Column column : data.getAfterColumnsList()) {
                if ("category_id".equalsIgnoreCase(column.getName())) {
                    categoryId = column.getValue();
                }
            }
        }

        return categoryId;
    }
}
